package springRepo.Library.repository.book;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import springRepo.Library.domain.book.Book;
import static springRepo.Library.repository.jdbc.DAOJDBCUtil.*;

@Repository("BookRepository")
public class BookRepositoryJDBC implements BookRepository{

	private static final Logger LOGGER = Logger.getLogger(BookRepositoryJDBC.class.getCanonicalName());
	
	private DataSource ds;
	
	@Autowired
	public BookRepositoryJDBC(DataSource ds){
		this.ds = ds;
	}
	
	public Book find(Integer id) {
		Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        Book book = null;
        
        try {
            connection = ds.getConnection();
            preparedStatement = connection.prepareStatement("select * from Book where id=?");
            preparedStatement.setInt(1, id);
            resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {
                book = (map(resultSet));
            }
        } catch (SQLException e) {
        	LOGGER.log(Level.SEVERE, e.getMessage());
        } finally {
            close(resultSet);
            close(preparedStatement);
            close(connection);
        }

        return book;
	}

	public List<Book> findAll() {
		Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        List<Book> books = new ArrayList<Book>();

        try {
            connection = ds.getConnection();
            preparedStatement = connection.prepareStatement("select * from Book");
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                books.add(map(resultSet));
            }
        } catch (SQLException e) {
        	LOGGER.log(Level.SEVERE, e.getMessage());
        } finally {
            close(resultSet);
            close(preparedStatement);
            close(connection);
        }

        return books;
	}

	public boolean create(Book book) {
		Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            connection = ds.getConnection();
            preparedStatement = connection.prepareStatement("INSERT INTO Book "
                    + "(name, author) VALUES (?, ?)");
            preparedStatement.setString(1, book.getName());
            preparedStatement.setString(2, book.getAuthor());
            preparedStatement.execute();
            return true;
        } catch (SQLException e) {
        	LOGGER.log(Level.SEVERE, e.getMessage());
        } finally {
            close(preparedStatement);
            close(connection);
        }
        return false;
	}

	public Book findByName(String bookName) {
		Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        Book book = null;

        try {
            connection = ds.getConnection();
            preparedStatement = connection.
                    prepareStatement("select * from Book where name = ?");
            preparedStatement.setString(1, bookName);
            resultSet = preparedStatement.executeQuery();
                      
            if(resultSet.next()) {
                book = map(resultSet);
            }
        } catch (SQLException e) {
        	LOGGER.log(Level.SEVERE, e.getMessage());
        } finally {
            close(resultSet);
            close(preparedStatement);
            close(connection);
        }

        return book;
	}

	private Book map(ResultSet resultSet) throws SQLException {
        Book book = new Book();
        book.setName(resultSet.getString(2));
        book.setAuthor(resultSet.getString(3));
        return book;
    }
}
